import unittest
import numpy as np
from Individual import Individual


def add(a, b):
    return a+b


def minus(a, b):
    return a-b


"""the variable"""
x = np.array([1, 2, 3, 4])
x1 = np.array([1, 2, 3, 4])
invx = Individual(x, 0.5)
invx1 = Individual(x1, 0.5)
x2 = np.array([2, 4, 6, 8])
invx2 = Individual(x2, 1)
xhalf = np.array([0.5, 1, 1.5, 2])


class TestDemo(unittest.TestCase):
    """Test mathfuc.py"""

    @classmethod
    def setUpClass(cls):
        print("this setupclass() method only called once.\n")

    @classmethod
    def tearDownClass(cls):
        print("this teardownclass() method only called once too.\n")

    def setUp(self):
        print("do something before test : prepare environment.\n")

    def tearDown(self):
        print("do something after test : clean up.\n")

    def test_mul_float(self):
        """Test method __mul__(float)"""
        invx.__mul__(0.5)
        self.assertEqual(xhalf.all(), invx.x.all())

    def test_mul_ndarray(self):
        """Test method __mul__(ndarray)"""
        invx1.__mul__(np.array([2, 2, 2, 2]))
        self.assertEqual(x2.all(), invx1.x.all())

    def test_mul_Individual(self):
        """Test method __mul__(individual)"""
        # because __mul__ change the Indiviudal we need to instantiate manys cases
        invx2.__mul__(invx2)
        ans = np.array([4, 16, 36, 64])
        self.assertEqual(ans.all(), invx2.x.all())

    def test_lt(self):
        """Test method __lt__(individual)"""
        self.assertEqual(True, invx.__lt__(invx2))


if __name__ == '__main__':
    unittest.main(verbosity=1)
